type Listener<Data> = (data: Data) => void;
const typeListenerMap: { [type: string]: Set<Listener<any>> } = {};
const SLATE_ITEM_CLICK = 'SlateItemClick';
const TOOLBAR_REFRESH = 'ToolbarRefresh';
const EDITOR_MOUSE_UP = 'EditorMouseUp';
const FORMAT_PAINTER = 'FormatPainter';

export const emit = <Data>(type: string, data: Data) => {
  Array.from(typeListenerMap[type] || []).forEach((listener) => {
    listener(data);
  });
};
export const on = <Data>(type: string, listener: Listener<Data>) => {
  const listenerSet = typeListenerMap[type] || new Set<Listener<Data>>();
  listenerSet.add(listener);
  typeListenerMap[type] = listenerSet;
};
export const off = <Data>(type: string, listener: Listener<Data>) => {
  typeListenerMap[type]?.delete(listener);
};
const createTypeEventHub = (type: string) => {
  const onTypeEvent = <Data>(listener: Listener<Data>) => on(type, listener);
  const offTypeEvent = <Data>(listener: Listener<Data>) => off(type, listener);
  const emitTypeEvent = <Data>(data?: Data) => emit(type, data);
  return [onTypeEvent, offTypeEvent, emitTypeEvent] as const;
};
export const [onSlateItemClick, offSlateItemClick, emitSlateItemClick] = createTypeEventHub(SLATE_ITEM_CLICK);
export const [onToolbarRefresh, offToolbarRefresh, emitToolbarRefresh] = createTypeEventHub(TOOLBAR_REFRESH);

export const [onEditorMouseUp, offEditorMouseUp, emitEditorMouseUp] = createTypeEventHub(EDITOR_MOUSE_UP);
export const [onFormatPainter, offFormatPainter, emitFormatPainter] = createTypeEventHub(FORMAT_PAINTER);
